import React, { useState, useMemo, useEffect } from 'react';
import { obj_str, filter_list, is_empty, HandView, Btn, useHigh, GridTable, filter_row, useCmd, WaitUmd, MainView, BtTxt, obj_int,
     loc_dt, for_obj, Title, stock_log, uDb, uJob, Ret, cline, InfoDlg, no_del, PanelFind, loc } from 'sui';
import { load_tp, load_part, get_col, load_col, get_ck } from './cmd';
import { User, useAccess } from 'cache';
import { DlgNum, DlgVal, DlgBuy } from './ctl';
import { Census } from './census';

const PartView = ({ hreturn, cur, map_supply, supply, set_kind }) => {
    const [main, setMain] = useState();
    const [kind, setKind] = useState();
    const [open_val, openVal] = useState(false);
    const [open_num, openNum] = useState(false);
    const [open_info, openInfo] = useState(false);
    const [open_buy, openBuy] = useState(false);
    const [col, setCol] = useState();
    const [high] = useHigh(140, 100);
    const umd = useCmd();
    const [no_acc] = useAccess();

    useEffect(() => {
        load_tp(cur, setKind);
        load_col(setCol);

        load_part(null, cur, setMain);
    }, [cur]);

    const getRow = useMemo(() => {
        const lst = filter_list(["sn"], col);
        return filter_row(main, lst, umd.filter);
    }, [main, umd.filter, col]);

    const pact = {
        "pick": v => openVal(true),
        "editnum": v => openNum(true),
        "del": (v) => {
            if (no_del()) {
                return;
            }

            uDb(null, "part/rm",
                {
                    line: cline(),
                    k: obj_str(v, "sn"),
                },
                r => load_part(umd.endWait, cur, setMain), e => umd.setErr());

            stock_log("lgpart", v.sn, "del", v);
        },
        "buy": () => openBuy(true),
    };

    const act = {
        "pick": (v) => {
            umd.startWait();

            uJob(null, "part/pick",
                {
                    line: cline(),
                    k: obj_str(umd.cur, "sn"),
                    num: obj_int(v, "num"),
                    pname: User.uName(),
                },
                r => load_part(umd.endWait, cur, setMain),
                e => umd.setErr());
        },
        "add": (val, h) => {
            umd.startWait();

            const tmp = {
                start: loc_dt(new Date()),
                tech: obj_str(cur, "sn"),
            };

            for_obj(val, (k, v) => {
                if (k === "tp") {
                    return;
                }

                tmp[k] = v;
            });

            const cmd = {
                line: cline(),
                tp: obj_str(val, "tp"),
                v: tmp,
            };

            uJob(null, "part/add", cmd,
                r => {
                    load_part(umd.endWait, cur, setMain);
                    if (h) {
                        h();
                    }
                },
                e => umd.setErr());
        },
        "edit": (v, h) => {
            uDb(null, "part/mditem",
                {
                    line: cline(),
                    v: v,
                },
                r => {
                    load_part(umd.endWait, cur, setMain);
                    if (h) {
                        h();
                    }
                }, e => umd.setErr());

            stock_log("lgpart", v.sn, "md", umd.cur);
        },
        "editnum": (v) => {
            uDb(null, "part/mditem",
                {
                    line: cline(),
                    v: {
                        "sn": obj_str(umd.cur, "sn"),
                        "dnum": obj_int(v, "dnum"),
                    }
                },
                r => load_part(umd.endWait, cur, setMain), e => umd.setErr());

            stock_log("lgpart", v.sn, "md", umd.cur);
        },
        "buy": (v) => {
            umd.startWait();

            uJob(null, "sale/order",
                {
                    line: cline(),
                    v: v,
                },
                r => {
                    umd.endWait();
                    openInfo(true);
                },
                e => umd.setErr());
        }
    };

    const getCol = useMemo(() => {
        if (is_empty(col)) {
            return null;
        }

        const tmp = [
            {name: loc("l_193"), key: 'index', width: 70, frozen: true},
            {name: loc("l_238"), key: 'e_opt', width: 310, formatter: (props) => {
                const d = props.row;
                return (
                    <div className="inline-flex">
                        <BtTxt hcmd={() => umd.pact(pact, d, "buy")} disabled={no_acc("pta1")}>{loc("l_552")}</BtTxt>
                        <BtTxt hcmd={() => umd.pact(pact, d, "pick")} disabled={no_acc("pta2")}>{loc("l_741")}</BtTxt>
                        <BtTxt hcmd={() => umd.pact(pact, d, "editnum")} disabled={no_acc("pta3")}>{loc("l_740")}</BtTxt>
                        <BtTxt hcmd={() => umd.pact(pact, d, "del")} disabled={no_acc("pta3")}>{loc("l_237")}</BtTxt>
                        <BtTxt hcmd={() => umd.pact(pact, d, "edit")} disabled={no_acc("pta3")}>{loc("l_235")}</BtTxt>
                    </div>
                );
            }},
        ];

        get_col(tmp, col, map_supply);

        return tmp;
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [col]);

    if (umd.isFin("census")) {
        return <Census hreturn={() => umd.hreturn()} kind={kind} data={main} cur={cur} col={getCol} supply={supply}/>;
    }

    const hCol = () => {
        if (is_empty(col) || !set_kind) {
            return null;
        }

        const ret = [];

        col.forEach(d => {
            const sn = obj_str(d, "sn");
            if (set_kind.has(sn)) {
                return;
            }

            if (d.sn === "supply") {
                d.ctp = "list";
                d.ctl = supply;
            } else if (d.sn === "tp") {
                d.ctl = kind;
            }

            ret.push(d);
        });

        return ret;
    };

    if (umd.isFin("add") || umd.isFin("edit")) {
        return <HandView umd={umd} title={loc("l_136")} act={act} col={hCol()} ck={get_ck(umd.cur, umd.value, col, set_kind)}/>;
    }

    const Right = () => (
        <div className="inline-flex">
            <Btn className="mx-4" color="green" hcmd={() => umd.pact(null, null, "add")} disabled={no_acc("pta3")}>{loc("l_239")}</Btn>
            <Ret hcmd={hreturn}/>
        </div>
    );

    const Left = () => {
        return (
            <div className="inline-flex items-center">
                <Title mod={obj_str(cur, "sn")} sub={loc("l_136")}>{obj_str(cur, "name")}</Title>
                <Btn className="ml-8" hcmd={() => umd.pact(null, null, "census")} color="teal">{loc("l_115")}</Btn>
            </div>
        );
    };

    const getMsg = () => {
        if (umd.isFin("pick")) {
            return loc("l_754");
        }

        return loc("l_562");
    };

    return (
        <MainView>
            <PanelFind left={<Left/>} right={<Right/>} hcmd={umd.setFilter}/>
            <GridTable col={getCol} row={getRow} high={high} gref={umd.gref}/>
            <DlgBuy open={open_buy} setOpen={openBuy} hcmd={(v) => umd.act(act, v)} data={umd.cur} col={col}/>
            <DlgVal open={open_val} hcmd={v => umd.act(act, v)} setOpen={openVal} data={umd.cur} col={col}/>
            <DlgNum open={open_num} hcmd={v => umd.act(act, v)} setOpen={openNum} data={umd.cur} col={col}/>
            <InfoDlg open={open_info} setOpen={openInfo} msg={getMsg()}/>
            <WaitUmd umd={umd}/>
        </MainView>
    );
};

export {PartView};
